﻿using AutoMapper;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using RBAC.Api.Demain.Entities;
using RBAC.Api.Erroc;
using RBAC.Api.Infaction;
using RBAC.Api.Read.Command.RBAC;
using RBAC.Api.Read.Common;
using RBAC.Api.Read.Dto;

namespace RBAC.Api.Read.CommandHandler.RBAC
{
    public class RefreshTokenQueryCommandHandler : IRequestHandler<RefreshTokenQueryCommand, APIResult<TokenResponseDto>>
    {
        private readonly IBaseRepositry<User> userRepository;
        private readonly IBaseRepositry<Role> roleRepository;
        private readonly IBaseRepositry<UserRole> userRoleRepository;
        private readonly TokenServices _tokenServices;
        private readonly IMapper mapper;
        private readonly ILogger<RefreshTokenQueryCommandHandler> logger1;

        public RefreshTokenQueryCommandHandler(IBaseRepositry<User> baseRepositry,
        IBaseRepositry<Role> baseRepositry1,
        IBaseRepositry<UserRole> baseRepositry2,
        TokenServices tokenServices,
        IMapper mapper,
       ILogger<RefreshTokenQueryCommandHandler> logger1
       )
        {
            userRepository = baseRepositry;
            roleRepository = baseRepositry1;
            userRoleRepository = baseRepositry2;
            _tokenServices = tokenServices;
            this.mapper = mapper;
            this.logger1 = logger1;
        }
        public Task<APIResult<TokenResponseDto>> Handle(RefreshTokenQueryCommand request, CancellationToken cancellationToken)
        {
            APIResult<TokenResponseDto> result = new APIResult<TokenResponseDto>();

            try
            {
                //判断参数是否为空
                if (string.IsNullOrEmpty(request.AccessToken) || string.IsNullOrEmpty(request.RefreshToken))
                {
                    logger1.LogWarning("刷新Token失败：Token参数为空");
                    result.Code = ResultCode.Fail;
                    result.Message = "Token为空";
                    return Task.FromResult(result);
                }

                //// 从过期的access token中获取principal
                var principal = _tokenServices.GetPrincipalFromExpiredToken(request.AccessToken);
                if (principal == null)
                {
                    logger1.LogWarning("刷新Token失败：无效的Token");
                    result.Code = ResultCode.Fail;
                    result.Message = "无效的Token";
                    return Task.FromResult(result);
                }

                var userId = int.Parse(principal.FindFirst("UserId").Value);
                var userName = principal.FindFirst("Nickname").Value;
                logger1.LogInformation($"刷新Token请求用户信息：用户ID={userId}，用户名={userName}");

                // 验证refresh token是否有效
                var storedRefreshToken = JsonConvert.DeserializeObject<RefreshToken>(request.RefreshToken);
                //验证是否有续期token  并且续期token是否过期 
                if (storedRefreshToken == null || storedRefreshToken.Expires < DateTime.Now)
                {
                    logger1.LogWarning($"刷新Token失败：刷新Token已过期，用户ID={userId}");
                    result.Code = ResultCode.Fail;
                    result.Message = "刷新Token已过期";
                    return Task.FromResult(result);
                }

                // 获取用户信息
                var user = userRepository.GetAll().AsNoTracking().FirstOrDefault(x => x.Id == userId);

                var userDto = mapper.Map<LoginDto>(user);
                //获取角色ID
                var roleId = userRoleRepository.GetAll().Where(x => x.UserId == user.Id).Select(x => x.RoleId).ToList();
                userDto.RoleId = string.Join(",", roleId);
                userDto.RoleName = string.Join(",", roleRepository.GetAll().Where(x => roleId.Contains(x.Id)).Select(x => x.RoleName));

                if (userDto == null)
                {
                    logger1.LogWarning($"刷新Token失败：用户不存在，用户ID={userId}");
                    result.Code = ResultCode.Fail;
                    result.Message = "用户不存在";
                    return Task.FromResult(result);
                }

                // 生成新的token
                var newAccessToken = _tokenServices.GenerateJwtToken(userDto);
                //生成新的刷新Token
                var newRefreshToken = _tokenServices.GenRefreshToken(userId);

                result.Code = ResultCode.Success;
                result.Message = "Token刷新成功";
                result.Data = new TokenResponseDto
                {
                    AccessToken = newAccessToken,
                    RefreshToken = newRefreshToken,
                };

                logger1.LogInformation($"Token刷新成功，用户ID={userId}，用户名={userName}");
                return Task.FromResult(result);
            }
            catch (Exception ex)
            {
                logger1.LogError(ex, $"刷新Token过程中出现异常：{ex.Message}");
                result.Code = ResultCode.Fail;
                result.Message = "刷新Token失败，服务器异常";
                return Task.FromResult(result);
            }
            finally
            {
                // 可以在这里添加必要的清理代码
            }
        }
    }
}
